/**
 * Free software.
 */

package org.nanhill.commons.pattern.dispatcher;

import java.util.LinkedList;

/**
 * Classic producter - consumer queue.
 * 
 * @author alin [xalinx at gmail dot com]
 * @date 2006-11-4
 */
public abstract class ClassicDispatcher<E> implements Dispatcher<E> {
	/**
	 * Work queue.
	 */
	private final LinkedList<E> queue = new LinkedList<E>();

	/**
	 * Stop flag.
	 */
	private volatile boolean stopped = false;

	public final void enqueue(E workItem) {
		synchronized (queue) {
			queue.add(workItem);
			queue.notify();
		}
	}

	public final void stop() {
		synchronized (queue) {
			stopped = true;
			queue.notify();
		}
	}

	public void start() throws InterruptedException {
		new WorkerThread().start();
	}

	private class WorkerThread extends Thread {
		public void run() {
			while (true) {
				E workItem = null;
				synchronized (queue) {
					try {
						while (queue.isEmpty() && !stopped)
							queue.wait();
					} catch (InterruptedException e) {
						continue;
					}
					if (stopped)
						break;
					workItem = queue.removeFirst();
				}
				send(workItem);
			}
		}
	}
}
